package custom.swing;

import java.util.ArrayList;
import java.util.Collection;

import javax.swing.AbstractListModel;

public class GenericListModel<T> extends AbstractListModel {

    private ArrayList<T> delegate = null;
    public static final long serialVersionUID = 1;

    public GenericListModel() {
        delegate = new ArrayList<T>();
    }

    public int getSize() {
        return delegate.size();
    }

    public T get(final int index) {
        return delegate.get(index);
    }

    public T getElementAt(int index) {
        return get(index);
    }

    public Object[] toArray() {
        return delegate.toArray();
    }

    public T[] toArray(final T[] a) {
        return delegate.toArray(a);
    }

    public void trimToSize() {
        delegate.trimToSize();
    }

    public void ensureCapacity(final int minCapacity) {
        delegate.ensureCapacity(minCapacity);
    }

    public boolean isEmpty() {
        return delegate.isEmpty();
    }

    public boolean contains(final Object elem) {
        return delegate.contains(elem);
    }

    public int indexOf(final Object elem) {
        return delegate.indexOf(elem);
    }

    public int lastIndexOf(final Object elem) {
        return delegate.lastIndexOf(elem);
    }

    public T set(final int index, final T elem) {
        T t = delegate.set(index, elem);
        fireContentsChanged(this, index, index);
        return t;
    }

    public T remove(final int index) {
        T t = delegate.remove(index);
        fireIntervalRemoved(this, index, index);
        return t;
    }

    public boolean remove(final Object elem) {
        boolean status = delegate.remove(elem);
        if (status) {
            int index = delegate.indexOf(elem);
            fireIntervalRemoved(this, index, index);
        }
        return status;
    }

    public void removeRange(final int fromIndex, final int toIndex) {
        if (fromIndex > toIndex) {
            throw new IllegalArgumentException("fromIndex must be <= toIndex");
        }
        for (int i = toIndex; i >= fromIndex; i--) {
            delegate.remove(i);
        }
        fireIntervalRemoved(this, fromIndex, toIndex);
    }

    public boolean add(final T elem) {
        int index = delegate.size();
        boolean status = delegate.add(elem);
        if (status) {
            fireIntervalAdded(this, index, index);
        }
        return status;
    }

    public void add(final int index, final T elem) {
        delegate.add(index, elem);
        fireIntervalAdded(this, index, index);
    }

    public boolean addAll(final Collection<? extends T> c) {
        int index0 = delegate.size();
        boolean status = delegate.addAll(c);
        if (status) {
            int index1 = delegate.size() - 1;
            fireIntervalAdded(this, index0, index1);
        }
        return status;
    }

    public boolean addAll(final int index0, final Collection<? extends T> c) {
        boolean status = delegate.addAll(index0, c);
        if (status) {
            int index1 = (c.size() - 1) + index0;
            fireIntervalAdded(this, index0, index1);
        }
        return status;
    }

    public void clear() {
        delegate.clear();
    }

    public String toString() {
        return delegate.toString();
    }
}
